package main

// 引入依赖包
import (
	"fmt"
	"go-learn/go_learn/obs"
	"os"
)

var ak = "EKYEXDZN81NZKWL5N0VQ"
var sk = "9lvCrqbNxIEfzw7wYNN8mBwofHpaFq0QtDpl3ZIZ"
var endpoint = "http://obs.cn-east-2.myhuaweicloud.com"
var bucketName = "oa-test"
var objectKey = "计算机网络自顶向下.pdf"
var filePath = "/opt/ebook/计算机网络自顶向下.pdf"

// 创建ObsClient结构体
var obsClient, _ = obs.New(ak, sk, endpoint)

func main() {
	// 初始化分段上传任务
	input := &obs.InitiateMultipartUploadInput{}
	input.Bucket = bucketName
	input.Key = objectKey
	output, err := obsClient.InitiateMultipartUpload(input)

	if err != nil {
		panic(err)
	}

	uploadId := output.UploadId

	fmt.Printf("UploadId:%s\n", uploadId)
	fmt.Println()

	// 每段上传100MB
	var partSize int64 = 100 * 1024 * 1024

	stat, err := os.Stat(filePath)
	if err != nil {
		panic(err)
	}
	fileSize := stat.Size()

	// 计算需要上传的段数
	partCount := int(fileSize / partSize)

	if fileSize%partSize != 0 {
		partCount++
	}

	// 执行并发上传段
	partChan := make(chan obs.Part, 5)

	for i := 0; i < partCount; i++ {
		partNumber := i + 1
		offset := int64(i) * partSize
		currPartSize := partSize
		if i+1 == partCount {
			currPartSize = fileSize - offset
		}
		go func() {
			uploadPartInput := &obs.UploadPartInput{}
			uploadPartInput.Bucket = bucketName
			uploadPartInput.Key = objectKey
			uploadPartInput.UploadId = uploadId
			uploadPartInput.SourceFile = filePath

			// 分段号
			uploadPartInput.PartNumber = partNumber
			// 分段在文件中的起始位置
			uploadPartInput.Offset = offset
			// 分段大小
			uploadPartInput.PartSize = currPartSize
			uploadPartInputOutput, err := obsClient.UploadPart(uploadPartInput)
			if err != nil {
				panic(err)
			}
			fmt.Printf("%d finished\n", partNumber)
			partChan <- obs.Part{ETag: uploadPartInputOutput.ETag, PartNumber: uploadPartInputOutput.PartNumber}
		}()
	}

	parts := make([]obs.Part, 0, partCount)

	// 等待上传完成
	for {
		part, ok := <-partChan
		if !ok {
			break
		}
		parts = append(parts, part)

		if len(parts) == partCount {
			close(partChan)
		}
	}

	completeMultipartUploadInput := &obs.CompleteMultipartUploadInput{}
	completeMultipartUploadInput.Bucket = bucketName
	completeMultipartUploadInput.Key = objectKey
	completeMultipartUploadInput.UploadId = uploadId
	completeMultipartUploadInput.Parts = parts
	// 合并段
	completeMultipartUploadOutput, err := obsClient.CompleteMultipartUpload(completeMultipartUploadInput)
	if err != nil {
		panic(err)
	}
	fmt.Printf("RequestId:%s\n", completeMultipartUploadOutput.RequestId)
}
